package com.smart.common.utils.hikVision;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.smart.common.core.domain.R;
import com.smart.common.exception.ServiceException;
import com.smart.common.jna.OTAPCMS;
import com.smart.common.utils.FormatData.JsonXmlUtils;
import com.smart.common.utils.StringUtils;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import lombok.Data;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.io.FileUtils;
import org.apache.http.HttpEntity;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Data
public class HikVisionTemplate {
    private String ip;
    private Short port;

    private String otapIp;

    private static Short otapPort;

    private String username;
    private String password;

    private static String otapKey;
    
    private static String addr;

    private static String title;

    public static int listenResult = -1;
    public static int iDeviceUserID = -1;
    public static OTAPCMS otapCMS = OTAPCMS.INSTANCE;
    public static OTAPCMS.OTAP_CMS_LISTEN_PARAM struCMSListenPara = new OTAPCMS.OTAP_CMS_LISTEN_PARAM();

    public static final int ENUM_OTAP_CMS_DEV_ON = 0;
    public static final int ENUM_OTAP_CMS_DEV_OFF = 1;
    public static final int ENUM_OTAP_CMS_ADDRESS_CHANGED = 2;
    public static final int ENUM_OTAP_CMS_DEV_AUTH = 3;
    public static final int ENUM_OTAP_CMS_DEV_DAS_REREGISTER = 7;
    public static final int ENUM_OTAP_CMS_DEV_DAS_OTAPKEY_ERROR = 9;
    public static final int ENUM_OTAP_CMS_DEV_SESSIONKEY_ERROR = 10;
    public static final int ENUM_OTAP_CMS_DAS_REQ = 13;

    //OTAP_CMS_CONFIG_DEV_ENUM
    public static final int OTAP_ENUM_OTAP_CMS_GET_MODEL_ATTR = 0;

    public static CMSCallback fRegisterCallBack = null;
    public static class CMSCallback implements OTAPCMS.OTAP_CMS_RegisterCallback {
        @Override
        public boolean invoke(int iUserID, int dwDataType, Pointer pOutBuffer, int dwOutLen, Pointer pInBuffer, int dwInLen, Pointer pUser) {
            System.out.println("CMSCallback, dwDataType:" + dwDataType + ", lUserID:" + iUserID);
            if (dwDataType == ENUM_OTAP_CMS_DEV_ON || dwDataType == ENUM_OTAP_CMS_ADDRESS_CHANGED || dwDataType == ENUM_OTAP_CMS_DEV_DAS_REREGISTER) {
                //OTAPCMS.OTAP_CMS_DEV_REG_INFO otapCmsDevRegInfo = new OTAPCMS.OTAP_CMS_DEV_REG_INFO();
                System.out.println("设备在线!, iUserID:"+ iUserID);
                iDeviceUserID = iUserID;
            } else if (dwDataType == ENUM_OTAP_CMS_DEV_OFF || dwDataType == ENUM_OTAP_CMS_DEV_SESSIONKEY_ERROR || dwDataType == ENUM_OTAP_CMS_DEV_DAS_OTAPKEY_ERROR) {
                System.out.println("设备离线!, iUserID:"+ iUserID);
            } else if (ENUM_OTAP_CMS_DEV_AUTH == dwDataType) {
                OTAPCMS.OTAP_CMS_DEV_REG_INFO pDevInfo = new OTAPCMS.OTAP_CMS_DEV_REG_INFO();
                pDevInfo.write();
                Pointer pDevRegInfo = pDevInfo.getPointer();
                pDevRegInfo.write(0, pOutBuffer.getByteArray(0, pDevInfo.size()), 0, pDevInfo.size());
                pDevInfo.read();
                String OTAPKey = otapKey;
                byte[] bs = new byte[32];
                String szOTAPKey = OTAPKey;
                bs = szOTAPKey.getBytes();
                pInBuffer.write(0, bs, 0, szOTAPKey.length()); //Set OTAP Key
                System.out.println("Device Dev Auth");
            } else if (ENUM_OTAP_CMS_DAS_REQ == dwDataType) {
                String ip = addr;
                String domain = addr;
                OTAPCMS.OTAP_CMS_DAS_INFO otapCmsDasInfo = new OTAPCMS.OTAP_CMS_DAS_INFO();
                otapCmsDasInfo.read();
                System.arraycopy(ip.getBytes(), 0, otapCmsDasInfo.struDevAddr.szIP, 0, ip.length());
                System.arraycopy(domain.getBytes(), 0,otapCmsDasInfo.byDomain , 0, domain.length());
                String szDasPort = String.valueOf(otapPort);
                String strServerID="das_"+ip+"_"+ szDasPort;
                System.arraycopy(strServerID.getBytes(), 0, otapCmsDasInfo.byServerID, 0, strServerID.length());
                otapCmsDasInfo.struDevAddr.wPort = otapPort;
                otapCmsDasInfo.write();
                dwInLen = otapCmsDasInfo.size();
                pInBuffer.write(0,otapCmsDasInfo.getPointer().getByteArray(0, dwInLen),0,dwInLen);
                System.out.println("Device DAS REQ");
            } else {
                System.out.println("Other Register Type, iUserID: " + iUserID + ", dwDataType:" + dwDataType);
            }
            return true;
        }
    }

    public void stopCMS() {
        otapCMS.OTAP_CMS_StopListen(listenResult);
    }

    public void finCMS()
    {
        if(!otapCMS.OTAP_CMS_Fini()) {
            System.out.println("停止海康SDK出错!");
        } else {
            System.out.println("停止海康SDK成功!");
        }
    }
    public boolean initCMS()
    {
        if(!otapCMS.OTAP_CMS_Init())
        {
            System.out.println("海康SDK初始化失败!");
            return false;
        }
        System.out.println("海康SDK初始化成功!");
        boolean b = otapCMS.OTAP_CMS_SetLogToFile(3, "./OTAPSDK_CMSLog", false);
        if (!b) {
            System.out.println("海康SDK日志设置出错! 错误信息:" + otapCMS.OTAP_CMS_GetLastError());
        }
        return true;
    }
    public void startCMS() {
        System.arraycopy(otapIp.getBytes(), 0, struCMSListenPara.struAddress.szIP, 0, otapIp.getBytes().length);
        struCMSListenPara.struAddress.wPort = otapPort;

        if(fRegisterCallBack == null) {
            fRegisterCallBack = new CMSCallback();
        }

        struCMSListenPara.fnCB = fRegisterCallBack;
        struCMSListenPara.write();

        listenResult = otapCMS.OTAP_CMS_StartListen(struCMSListenPara);
        if (listenResult < 0) {
            System.out.println("启动监听出错:\"" + otapCMS.OTAP_CMS_GetLastError());
        } else {
            System.out.println("启动监听成功:, IP:" + otapIp + " Port:" + struCMSListenPara.struAddress.wPort);
        }

    }
    public static class BYTE_ARRAY extends Structure {
        public byte[] byValue;
        public BYTE_ARRAY(int iLen) {
            byValue = new byte[iLen];
        }
        @Override
        protected List<String> getFieldOrder() {
            return Arrays.asList("byValue");
        }
    }

    /**
     * 透传
     * @param url
     * @param body
     * @return
     */
    public R<String> iSAPIPassThrough(String url, String body) {
        url = url+"\0";
        OTAPCMS.OTAP_CMS_ISAPI_PT_PARAM pParam = new OTAPCMS.OTAP_CMS_ISAPI_PT_PARAM();

        BYTE_ARRAY url_array = new BYTE_ARRAY(2*1024);
        System.arraycopy(url.getBytes(), 0, url_array.byValue, 0, url.getBytes().length);
        url_array.write();

        BYTE_ARRAY body_array = new BYTE_ARRAY(2*1024);
        System.arraycopy(body.getBytes(), 0, body_array.byValue, 0, body.getBytes().length);
        body_array.write();

        BYTE_ARRAY pOutput = new BYTE_ARRAY(1024 * 100);
        pOutput.read();
        pParam.pRequestUrl = url_array.getPointer();
        pParam.dwRequestUrlLen = url.getBytes().length;
        pParam.pInBuffer = body_array.getPointer();
        pParam.dwInSize = body.getBytes().length;
        pParam.pOutBuffer = pOutput.getPointer();
        pParam.dwOutSize = 1024 * 100;
        pParam.write();
        boolean b = this.otapCMS.OTAP_CMS_ISAPIPassThrough(iDeviceUserID, pParam);
        R<String> res = new R<>();
        if (!b){
            res.setCode(0);
            res.setMsg("OTAP_CMS_GetLastError: " + otapCMS.OTAP_CMS_GetLastError());
            res.setData("");
            System.out.println("OTAP_CMS_GetLastError: " + otapCMS.OTAP_CMS_GetLastError() );
        }else{
            pOutput.read();
            System.out.println("OTAP_CMS_ISAPIPassThrough成功，outBuf" + new String(pOutput.byValue).trim());
            res.setCode(1);
            res.setMsg("OK");
            res.setData(new String(pOutput.byValue).trim());
        };
        return res;
    }
    /**
     * {
     *     "UserInfoDetail": {
     *         "mode": {
     *             "@opt": "all,byEmployeeNo"
     *         },
     *         "EmployeeNoList": {
     *             "maxSize": 100000,
     *             "employeeNo": {
     *                 "@min": 1,
     *                 "@max": 32
     *             }
     *         }
     *     }
     * }
     * @param json
     */
    public void deleteUser(String json) {
        JSONObject jsonObject = null;
        try {
            jsonObject = this.send(HikVisionRUL.PERSON_DELETE,json);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("删除用户失败!");
        }
    }

    public String getHttpUrl(){
        return "http://"+ip+":"+port;
    }
    public String getHttpsUrl(){
        return "https://"+ip+":"+port;
    }
    public HikVisionTemplate(String ip,Short port,String username,String password,String otapIp,Short otapPort,String otapKey,String addr,String title) {
        this.ip = ip;
        this.port = port;
        this.username = username;
        this.password = password;
        this.otapIp = otapIp;
        this.otapPort = otapPort;
        this.otapKey = otapKey;
        this.addr = addr;
        this.title = title;
    }

    /**
     * 下发人员
     *
     * @return
     */
    public JSONObject downloadUser(String downUser){
        JSONObject jsonObject = null;
        try {

            jsonObject = this.send(HikVisionRUL.PERSON_DOWNLOAD,downUser);
        } catch (Exception e) {
            throw new ServiceException("新增用户失败!");
        }
        return jsonObject;
    }

    public JSONObject send(String apiUrl, String params) throws Exception {
        Http http = new Http(apiUrl);
        switch (http.type) {
            case GET:
                return toGet(http.getUrl());
            case POST:
                return toPost(http.getUrl(), params);
            case PUT:
                return toPut(http.getUrl(), params);
            case DELETE:
//                return toPost(apiUrl, "");
            default:
                throw new RuntimeException("HttpType is error!");
        }
    }

    private JSONObject toPut(String apiUrl, String params) throws IOException {
        // import org.apache.commons.httpclient.HttpClient;
        String url = getHttpUrl() + "/" + apiUrl;
        // 设置用户名和密码
        CredentialsProvider provider = new BasicCredentialsProvider();
        provider.setCredentials(AuthScope.ANY,
                new UsernamePasswordCredentials(username, password));
        // 创建HttpClient实例
        CloseableHttpClient client = HttpClients.custom()
                .setDefaultCredentialsProvider(provider)
                .build();
        HttpPut method = new HttpPut(url);
        method.setHeader("Content-Type", "application/json");
        // 设置请求体
        method.setEntity(new StringEntity(params, "UTF-8"));

        CloseableHttpResponse response = client.execute(method);
        if (response.getStatusLine().getStatusCode()==200) {
            HttpEntity entity = response.getEntity();
            String s = EntityUtils.toString(entity, "utf-8");
            if (JsonXmlUtils.isJson(s)) {
                return JSONObject.parseObject(s);
            }
            JSONObject jsonObject = JsonXmlUtils.toJson(s);
            return jsonObject;
        }else{
            System.out.println(response.getEntity().toString());
            throw new ServiceException("请求失败!");
        }

    }

    public JSONObject toGet(String apiUrl) throws IOException {
        // import org.apache.commons.httpclient.HttpClient;
        String url = getHttpUrl() + "/" + apiUrl;
        // 设置用户名和密码
        CredentialsProvider provider = new BasicCredentialsProvider();
        provider.setCredentials(AuthScope.ANY,
                new UsernamePasswordCredentials(username, password));
        // 创建HttpClient实例
        CloseableHttpClient client = HttpClients.custom()
                .setDefaultCredentialsProvider(provider)
                .build();
        HttpGet method = new HttpGet(url);
        method.setHeader("Content-Type", "application/json");
        CloseableHttpResponse response = client.execute(method);
        HttpEntity entity = response.getEntity();
        String s = EntityUtils.toString(entity, "utf-8");
        if (JsonXmlUtils.isJson(s)) {
            return JSONObject.parseObject(s);
        }
        JSONObject jsonObject = JsonXmlUtils.toJson(s);
        return jsonObject;
    }

    public JSONObject toPost(String apiUrl, String requestBody) throws Exception {
        String url = getHttpUrl() + "/" + apiUrl;

        // 设置用户名和密码
        CredentialsProvider provider = new BasicCredentialsProvider();
        provider.setCredentials(AuthScope.ANY,
                new UsernamePasswordCredentials(username, password));

        // 创建HttpClient实例
        CloseableHttpClient client = HttpClients.custom()
                .setDefaultCredentialsProvider(provider)
                .build();

        // 创建HttpPost实例
        HttpPost method = new HttpPost(url);
        method.setHeader("Content-Type", "application/json]");

        // 设置请求体
        method.setEntity(new StringEntity(requestBody, "UTF-8"));

        // 执行POST请求
        CloseableHttpResponse response = client.execute(method);
        System.out.println(response.toString());

        // 获取响应实体
        HttpEntity entity = response.getEntity();
        if(response.getStatusLine().getStatusCode()!=200){
            System.out.println(entity);
            throw new ServiceException("请求异常!"+entity.toString());
        }
        // 转换响应实体为JSON对象
        String result = EntityUtils.toString(entity, "UTF-8");
        JSONObject jsonObject = JSONObject.parseObject(result);
        // 关闭资源
        EntityUtils.consume(entity);
        response.close();
        return jsonObject;
    }

    public void formatUrl(String url) {

    }

    /**
     * 查询用户人脸机消费次数
     * @return
     */
    public JSONObject getConsumptionData(String userCard, Date syncTime) {
        JSONObject transactionRecordEventCond = new JSONObject();
        transactionRecordEventCond.put("searchID","*");
        transactionRecordEventCond.put("searchResultPosition",0);
        transactionRecordEventCond.put("employeeNoString",userCard);
        transactionRecordEventCond.put("maxResults",100000);
        transactionRecordEventCond.put("startTime",syncTime==null?"2000-01-01T00:00:00+08:00":getString(syncTime));
        transactionRecordEventCond.put("endTime","2037-09-14T10:39:38+08:00");
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("TransactionRecordEventCond",transactionRecordEventCond);
        String params = jsonObject.toJSONString();
        JSONObject send = null;
        try {
            send = send(HikVisionRUL.PERSON_CONSUMPTION_DATA, params);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return send;
    }

    private static String getString(Date syncTime) {
        // 将Date转换为Instant
        Instant instant = syncTime.toInstant();
        // 指定时区为UTC+08:00
        ZonedDateTime zonedDateTime = instant.atZone(java.time.ZoneOffset.ofHours(8));
        // 创建DateTimeFormatter
        DateTimeFormatter formatter = DateTimeFormatter.ISO_ZONED_DATE_TIME;
        // 格式化日期时间为字符串
        String formattedDateTime = zonedDateTime.format(formatter);
        return formattedDateTime;
    }

    @Data
    public class Http {
        private HttpType type;
        private String url;

        public Http() {
        }

        public Http(String apiUrl) {
            if (StringUtils.isEmpty(apiUrl) || StringUtils.isBlank(apiUrl)) {
                throw new RuntimeException("apiUrl is null!");
            }
            try {
                String[] s = apiUrl.split(" ");
                this.type = HttpType.fromValue(s[0]);
                this.url = s[1];
            } catch (Exception e) {
                throw new RuntimeException("数据转换异常!");
            }
        }
    }

    public enum HttpType {
        GET("GET"),
        POST("POST"),
        PUT("PUT"),
        DELETE("DELETE");

        private final String value;

        HttpType(String value) {
            this.value = value;
        }

        public String getValue() {
            return value;
        }

        // 新增一个静态方法来根据值获取枚举
        public static HttpType fromValue(String value) {
            for (HttpType method : values()) {
                if (method.getValue().equalsIgnoreCase(value)) {
                    return method;
                }
            }
            throw new IllegalArgumentException("Invalid HTTP method value: " + value);
        }
    }

    public static String httpSocket(String Method, String szAddress, String URL, String szboundary, byte[] byBodyParam, boolean bAuth, String AuthInfo) throws IOException {
        java.net.URL httpurl = new URL(szAddress + URL);
        HttpURLConnection httpConn = (HttpURLConnection) httpurl.openConnection();
        //表单格式发送数据
        httpConn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + szboundary);
        if (bAuth) {
            httpConn.setRequestProperty("Authorization", AuthInfo); //带上认证字段
        }
        httpConn.setRequestMethod(Method);
        httpConn.setDoInput(true);
        httpConn.setDoOutput(true);
        httpConn.setConnectTimeout(20000);
        httpConn.setReadTimeout(20000);
        httpConn.setUseCaches(false);
        httpConn.connect();

        OutputStream outputData = httpConn.getOutputStream();
        outputData.write(byBodyParam); //输入表单数据
        outputData.flush();
        outputData.close();

        String authorization = "";
        if (httpConn.getResponseCode() == 200) {
            InputStream inputData = httpConn.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputData));
            String str;
            System.out.println("输出: ");
            while ((str = reader.readLine()) != null)
                System.out.println(str);
            inputData.close();
        } else if (httpConn.getResponseCode() == 401) {
            authorization = httpConn.getHeaderField("WWW-Authenticate");
        } else {
            System.out.println("getResponseCode: " + httpConn.getResponseCode());
            InputStream errData = httpConn.getErrorStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(errData));
            System.out.println("输出: ");
            String str;
            while ((str = reader.readLine()) != null)
                System.out.println(str);
            errData.close();
        }
        httpConn.disconnect();

        return authorization;
    }

    public void setUserInfoAndFace(String username, String userCard, MultipartFile file) {
        Http http = new Http(HikVisionRUL.PERSON_DOWNLOAD);
        String szboundary = "--------------------------779209770667596196161432";

        JSONObject valid = new JSONObject();
        valid.put("enable", true);
        valid.put("beginTime", "2000-12-05T00:00:00+08:00");
        valid.put("endTime", "2030-12-06T00:00:00+08:00");

        JSONObject plan1 = new JSONObject();
        plan1.put("doorNo", 1);
        JSONArray planTemplateNo1 = new JSONArray();
        planTemplateNo1.add(1);
        plan1.put("planTemplateNo", planTemplateNo1);
        JSONArray rightPlan = new JSONArray();
        rightPlan.add(plan1);

        JSONObject face = new JSONObject();
        face.put("FDID", "1");
        face.put("faceID", 1);
        face.put("faceName", "facePicture");
        JSONArray list = new JSONArray();
        list.add(face);

        JSONObject faceInfo = new JSONObject();
        faceInfo.put("List", list);

        JSONObject userInfoAndRight = new JSONObject();
        userInfoAndRight.put("employeeNo", userCard);
        //不知道本地是什么编码,所以强制转换为utf-8
        userInfoAndRight.put("name", username);
        userInfoAndRight.put("userType", "normal");
        userInfoAndRight.put("Valid", valid);
        userInfoAndRight.put("password", "");
        userInfoAndRight.put("RightPlan", rightPlan);
        userInfoAndRight.put("localUIRight", false);
        userInfoAndRight.put("userVerifyMode", "face");
        userInfoAndRight.put("FaceInfo", faceInfo);

        JSONObject input = new JSONObject();
        input.put("UserInfoAndRight", userInfoAndRight);

        //组装报文
        StringBuffer buffer1 = new StringBuffer();
        buffer1.delete(0, buffer1.length());

        buffer1.append("--" + szboundary + "\r\n");
        buffer1.append("Content-Disposition: form-data; name=\"UserInfoAndRight\"\r\n");
        buffer1.append("Content-Type: application/json\r\n");
        buffer1.append("\r\n");
        System.out.println("jsonObject: " + input.toString());
        buffer1.append(input.toString());
        buffer1.append("\r\n");

        buffer1.append("--" + szboundary + "\r\n");
        System.out.println(file.getName());
        System.out.println(file.getOriginalFilename());
        buffer1.append("Content-Disposition: form-data; name=\"facePicture\"; filename=\"01.jpg\"\r\n");
        buffer1.append("Content-Type: image/jpeg\r\n");
        buffer1.append("\r\n");

        //报文结尾
        StringBuffer buffer2 = new StringBuffer();
        buffer2.append("\r\n");
        buffer2.append("--" + szboundary + "\r\n");

        //第一次不带认证信息，先不发送二进制数据
        int iBodyLength = buffer1.length() + buffer2.length();
        byte[] byBodyParam = new byte[iBodyLength];
        System.arraycopy(buffer1.toString().getBytes(), 0, byBodyParam, 0, buffer1.length());
        System.arraycopy(buffer2.toString().getBytes(), 0, byBodyParam, buffer1.length(), buffer2.length());

        String authorization = null;
        try {
            authorization = httpSocket(http.getType().value, getHttpUrl()+http.getUrl(),

                    http.getUrl(), szboundary,
                    byBodyParam, false, "");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        if (authorization != null && !"".equals(authorization)) {
            //计算认证信息
            String qop = "";
            String realm = "";
            String nonce = "";
            String[] strAuthInfo = authorization.split(",");
            for (int i = 0; i < strAuthInfo.length; i++) {
                System.out.println(strAuthInfo[i]);
                if (strAuthInfo[i].contains("qop")) {
                    qop = strAuthInfo[i].substring(strAuthInfo[i].indexOf("\"") + 1, strAuthInfo[i].lastIndexOf("\""));
                    System.out.println("qop: " + qop);
                }
                if (strAuthInfo[i].contains("realm")) {
                    realm = strAuthInfo[i].substring(strAuthInfo[i].indexOf("\"") + 1, strAuthInfo[i].lastIndexOf("\""));
                    System.out.println("realm: " + realm);
                }
                if (strAuthInfo[i].contains("nonce")) {
                    nonce = strAuthInfo[i].substring(strAuthInfo[i].indexOf("\"") + 1, strAuthInfo[i].lastIndexOf("\""));
                    System.out.println("nonce: " + nonce);
                }

            }

            String A1 = this.getUsername() + ":" + realm + ":" + this.getPassword();
            String A2 = http.getType()+":"+http.getUrl();

            MessageDigest md5 = null;
            try {
                md5 = MessageDigest.getInstance("MD5");
            } catch (NoSuchAlgorithmException e) {
                throw new RuntimeException(e);
            }
            byte[] bMD5_A1 = md5.digest(A1.getBytes());
            String szMD5_A1 = Hex.encodeHexString(bMD5_A1);

            byte[] bMD5_A2 = md5.digest(A2.getBytes());
            String szMD5_A2 = Hex.encodeHexString(bMD5_A2);

            String nc = "00000001";
            String cnonce = UUID.randomUUID().toString().replaceAll("-", "");
            String resContent = szMD5_A1 + ":" + nonce + ":" + nc + ":" + cnonce + ":" + qop + ":" + szMD5_A2;
            byte[] bMD5_Content = md5.digest(resContent.getBytes());
            String response = Hex.encodeHexString(bMD5_Content);

            String AuthInfo = "Digest username=\""+this.getUsername()+"\", "
                    + "realm=\"" + realm + "\", "
                    + "nonce=\"" + nonce + "\", "
                    + "uri="+http.getUrl()+", algorithm=\"MD5\", "
                    + "qop=" + qop + ", nc=00000001, cnonce=\"" + cnonce + "\", "
                    + "response=\"" + response + "\"";

            //获取上传的文件名
            String fileName = file.getOriginalFilename();
            // 获取文件后缀名
            String suffix = fileName.substring(fileName.lastIndexOf("."));
            // 用uuid作为文件名，防止生成的临时文件重复
            File dest = null;
            try {
                dest = File.createTempFile(UUID.randomUUID().toString(), suffix);
                // 将上传文件复制到临时文件
                FileUtils.copyInputStreamToFile(file.getInputStream(), dest);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }



            File tfile = dest;
            //读取本地文件中的二进制数据
            FileInputStream uploadPic = null;
            byte[] bytePic = null;
            try {
                uploadPic = new FileInputStream(tfile);
                int iFileLen = uploadPic.available();
                bytePic = new byte[iFileLen];
                uploadPic.read(bytePic);
            } catch (FileNotFoundException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }


            int iBodyLength2 = buffer1.length() + bytePic.length + buffer2.length();
            byte[] byBodyParam2 = new byte[iBodyLength2];
            System.arraycopy(buffer1.toString().getBytes(), 0, byBodyParam2, 0, buffer1.length());
            System.arraycopy(bytePic, 0, byBodyParam2, buffer1.length(), bytePic.length);
            System.arraycopy(buffer2.toString().getBytes(), 0, byBodyParam2, buffer1.length() + bytePic.length, buffer2.length());

            //第二次请求带上认证字段
            try {
                httpSocket(http.getType().value, this.getHttpUrl(),
                        http.getUrl(), szboundary,
                        byBodyParam2, true, AuthInfo);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

        }
    }
}
